package com.ml.loan.common.utils;

import com.google.common.collect.Maps;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * 概率命中
 * @Author Mickey
 * @Date 2021/3/4 0:48
 **/
public class ProbabilityHitUtil {

    /**
     * 根据比例判断是否命中
     **/
    public static boolean isHit(Double hitRate){
        if (hitRate >= 1) { return true; }
        if (hitRate <= 0) { return false; }
        // 存储概率
        List<Double> orignalRates = new ArrayList<>(2);
        orignalRates.add(hitRate);
        orignalRates.add(1 - hitRate);
        int hit = calc(orignalRates);
        return hit == 0?true:false;
    }

    public static int calc(List<Double> orignalRates) {
        if (orignalRates == null || orignalRates.isEmpty()) {
            return -1;
        }
        int size = orignalRates.size();

        // 计算总概率，这样可以保证不一定总概率是1
        double sumRate = 0d;
        for (double rate : orignalRates) {
            sumRate += rate;
        }

        // 计算每个场景在总概率的基础下的概率情况
        List<Double> sortOrignalRates = new ArrayList<>(size);
        Double tempSumRate = 0d;
        for (double rate : orignalRates) {
            tempSumRate += rate;
            sortOrignalRates.add(tempSumRate / sumRate);
        }

        // 根据区块值来获取命中的场景索引
        double nextDouble = Math.random();
        sortOrignalRates.add(nextDouble);
        Collections.sort(sortOrignalRates);

        return sortOrignalRates.indexOf(nextDouble);
    }

    public static void main(String[] args) {
        Map<String, Integer> count = Maps.newHashMap();
        double num = 10000000;
        for (int i = 0; i < num; i++) {
            boolean orignalIndexf = isHit(0.3);
            String orignalIndex = orignalIndexf?"命中":"未命中";
            Integer value = count.get(orignalIndex);
            count.put(orignalIndex, value == null ? 1 : value + 1);
        }
        for (Map.Entry<String, Integer> entry : count.entrySet()) {
            System.out.println(entry.getKey() + ", 命中次数=" + entry.getValue() + ", 实际概率="+ entry.getValue() / num);
        }
    }

}
